package com.wusongti.performance.controller;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import com.wusongti.performance.model.params.OpenMonitorParameter;
import com.wusongti.performance.model.params.PerformanceLogSearchParameter;
import com.wusongti.performance.model.vo.CommonResponseVO;
import com.wusongti.performance.model.vo.OpenMonitorVO;
import com.wusongti.performance.model.vo.PerformanceLogVO;
import com.wusongti.performance.service.IPerformanceLogService;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;

/**
 * @ClassName: HomeController
 * @author: wust
 * @date: 2022/04/28 16:54
 * @Description: 控制器
 */
@Controller
class HomeController {
    /**
     * cmd进程列表
     */
    private static final HashSet<Process> cmdProcess = new HashSet<Process>();

    @Autowired
    private IPerformanceLogService performanceLogService;

    @Autowired
    private Environment env;

    /**
     * 跳转到首页
     *
     * @param model
     * @return
     */
    @GetMapping("/")
    String index(Model model) {
        model.addAttribute("now", LocalDateTime.now());
        return "index";
    }

    /**
     * 把日志保存到数据库
     *
     * @return
     */
    @PostMapping("save")
    @ResponseBody
    public CommonResponseVO save() {
        final CommonResponseVO webResponseDto = new CommonResponseVO();
        performanceLogService.batchSave();
        return webResponseDto;
    }

    /**
     * 查询所有日志
     *
     * @return
     */
    @GetMapping("findAll")
    @ResponseBody
    public CommonResponseVO findAll(@RequestParam(required = false) String methodName, @RequestParam(required = false) Integer threadId,
        @RequestParam(required = false) String createDate, @RequestParam(required = false) String typeName) {
        final CommonResponseVO webResponseDto = new CommonResponseVO();

        final PerformanceLogSearchParameter parameter = new PerformanceLogSearchParameter();
        parameter.setTypeName(typeName);
        parameter.setMethodName(methodName);
        parameter.setThreadId(threadId);
        parameter.setCreateDate(createDate);

        final List<PerformanceLogVO> list = performanceLogService.findAll(parameter);

        webResponseDto.setLstDto(list);

        return webResponseDto;
    }

    /**
     * 删除数据库日志
     *
     * @return
     */
    @PostMapping("deleteAllLog")
    @ResponseBody
    public CommonResponseVO deleteAllLog() {
        final CommonResponseVO webResponseDto = new CommonResponseVO();
        performanceLogService.deleteAll();
        return webResponseDto;
    }

    /**
     * 查询所有进程ID和脚本列表
     *
     * @return
     */
    @GetMapping("findPidAndScript")
    @ResponseBody
    public CommonResponseVO findPidAndScript() {
        final CommonResponseVO webResponseDto = new CommonResponseVO();

        final OpenMonitorVO openMonitorVO = new OpenMonitorVO();

        final String dir = env.getProperty("sysprop.script-dir");

        final List<String> scriptNameList = FileUtil.listFileNames(dir);

        if (scriptNameList != null && scriptNameList.size() > 0) {
            final List<String> scriptNameListNew = new ArrayList<String>(scriptNameList.size());
            for (String s : scriptNameList) {
                scriptNameListNew.add(s);
            }
            openMonitorVO.setScriptNameList(scriptNameListNew);
        }

        final ArrayList<String> pidList = getJavaPid();
        openMonitorVO.setPidList(pidList);

        webResponseDto.setObj(openMonitorVO);

        return webResponseDto;
    }

    /**
     * 打开监控
     *
     * @return CommonResponseVO
     */
    @PostMapping("openMonitor")
    @ResponseBody
    public CommonResponseVO openMonitor(@RequestBody OpenMonitorParameter openMonitorParameter) {
        final CommonResponseVO webResponseDto = new CommonResponseVO();

        final String pidStr = openMonitorParameter.getPidStr();

        final String[] pids = pidStr.split("_");

        if (pids.length != 2 || StrUtil.isEmptyIfStr(pids[1])) {
            webResponseDto.setFlag(CommonResponseVO.INFO_WARNING);
            webResponseDto.setMessage("进程格式有无。");
            return webResponseDto;
        }

        final List<String> scriptNameList = openMonitorParameter.getScriptNameList();

        final String logDir = env.getProperty("sysprop.log-dir");

        if (!FileUtil.exist(logDir)) {
            new File(logDir).mkdirs();
        }

        final String scriptDir = env.getProperty("sysprop.script-dir");

        for (String s : scriptNameList) {
            final StringBuffer cmd = new StringBuffer("btrace -o");
            cmd.append(" ");
            cmd.append(logDir).append(s.replace("class", "txt"));
            cmd.append(" ");
            cmd.append(pids[0]);
            cmd.append(" ");
            cmd.append(scriptDir + s);

            try {

                ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", cmd.toString());

                final Process pro = pb.start();

                cmdProcess.add(pro);

                int exitVal = pro.waitFor();

                System.out.println("Exited with error code " + exitVal);

            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }

        return webResponseDto;
    }

    /**
     * 关闭监控
     *
     * @return
     */
    @PostMapping("closeMonitor")
    @ResponseBody
    public CommonResponseVO closeMonitor() {
        final CommonResponseVO webResponseDto = new CommonResponseVO();

        int size = 0;

        if (cmdProcess != null && cmdProcess.size() > 0) {
            for (Process process : cmdProcess) {

                if (process.isAlive()) {
                    process.destroy();
                }

                size++;
            }

            cmdProcess.clear();
        }

        final String rs = "一共关闭了" + size + "个进程";

        webResponseDto.setMessage(rs);

        return webResponseDto;
    }

    /**
     * 通过jps命令查找进程id
     *
     * @return
     */
    public ArrayList<String> getJavaPid() {

        final ArrayList<String> list = new ArrayList<String>();

        Runtime runtime = Runtime.getRuntime();

        try {
            BufferedReader br =
                new BufferedReader(new InputStreamReader(runtime.exec("jps").getInputStream(), "GB2312"));

            String line;

            while ((line = br.readLine()) != null) {

                if (line == null || line.trim().length() == 0) {

                    continue;

                }

                list.add(line.replace(" ", "_"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return list;
    }
}
